package com.killer.catalina;

import com.killer.util.HttpProtocolUtil;
import com.killer.view.Request;
import com.killer.view.Response;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang.StringUtils;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.Node;
import org.dom4j.io.SAXReader;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.rmi.server.ServerCloneException;
import java.util.ArrayList;
import java.util.List;

/**
 * context的实现类
 */
public class StandardContext implements Context {


    /**
     * web.xml配置文件路径
     */
    protected String configFile = "WEB-INF/web.xml";
    /**
     * 应用部署的路径
     */
    private String docBase;

    /**
     * 应用映射的path
     */
    public String path;

    /**
     * 保存对当前虚拟主机的引用
     */
    private StandardHost host;

    /**
     * 该应用下的servlet
     */
    private List<StandardWrapper> wrapperList=new ArrayList<StandardWrapper>();

    public List<StandardWrapper> getWrapperList() {
        return wrapperList;
    }

    public void setWrapperList(List<StandardWrapper> wrapperList) {
        this.wrapperList = wrapperList;
    }

    public StandardHost getHost() {
        return host;
    }

    public void setHost(StandardHost host) {
        this.host = host;
    }

    public String getDocBase() {
        return docBase;
    }

    public void setDocBase(String docBase) {
        this.docBase = docBase;
    }

    public String getPath() {
        return path;
    }

    public void setPath(String path) {
        this.path = path;
    }

    @Override
    public void start() {
        //扫描应用程序的web.xml，注册Servlet组件
        File file=loadConfigFile();
        if (!file.exists()) {
            throw new RuntimeException(this.getDocBase() + "未找到对应的web.xml");
        }
        SAXReader reader=new SAXReader();
        try {
            Document document = reader.read(new FileInputStream(file));
            //获取根标签 <web-app>
            Element rootElement = document.getRootElement();
            //获取下面的servlet标签,封装成Wrapper对象
            List<Element> servletElements = rootElement.selectNodes("//servlet");
            if (CollectionUtils.isNotEmpty(servletElements)) {
                for (Element servletElement : servletElements) {
                    StandardWrapper wrapper=new StandardWrapper();
                    //获取serveltName标签
                    Node nameNode = servletElement.selectSingleNode("servlet-name");
                    wrapper.setName(nameNode.getStringValue());
                    Node classNode=servletElement.selectSingleNode("servlet-class");
                    wrapper.setClassName(classNode.getStringValue());
                    // 根据servlet-name的值找到url-pattern
                    Element servletMappingElement = (Element) rootElement.selectSingleNode("/web-app/servlet-mapping[servlet-name='" + wrapper.getName() + "']");
                    Node pathNode = servletMappingElement.selectSingleNode("url-pattern");
                    wrapper.setPath(pathNode.getStringValue());
                    wrapperList.add(wrapper);
                }
            }
        } catch (DocumentException e) {
            throw new RuntimeException(e);
        } catch (FileNotFoundException e) {
            throw new RuntimeException(e);
        }
    }

    private File loadConfigFile(){
        //获取MinCat目录
        String homeDir = System.getProperty("catalina.home");
//        <Host name="localhost"  appBase="webapps"
//        unpackWARs="true" autoDeploy="true">
        String appBase = host.getAppBase();
//        <Context docBase="webDemo01" path="/webDemo01"/>
        String appName=this.getDocBase();
        if (StringUtils.isBlank(homeDir)) {
            homeDir =".";
        }

        String filePath= appBase.startsWith("/")?appBase+File.separator+appName+File.separator+configFile:homeDir+File.separator+appBase+File.separator+appName+File.separator+configFile;
        return new File(filePath);
    }

    public StandardWrapper mapperWrapper(Request request, Response response) throws IOException {
        if (CollectionUtils.isEmpty(wrapperList)) {
            response.response(HttpProtocolUtil.getRep404Header());
        }
        for (Wrapper wrapper : wrapperList) {
            //    /webDemo01/index.html
            //由于MiniCat默认都必须给应用命名，因此/至少2个，实际情况是可以一个的，获取第一个/和第二个/之间的内容
            String path=request.getPath();
            String servletPath = path.substring(path.indexOf("/", 1));
            StandardWrapper standardWrapper=(StandardWrapper)wrapper;
            if (StringUtils.equals(servletPath, standardWrapper.getPath())) {
                return standardWrapper;
            }
        }
        return null;
    }
}
